﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;

namespace Xfs
{
    [XfsObjectSystem]
    public class XfsPatrolComponentStartSystem : XfsStartSystem<XfsPatrolComponent>
    {
        public override async void Start(XfsPatrolComponent self)
        {
            await XfsGame.XfsSence.GetComponent<XfsTimerComponent>().WaitAsync(4000);

            self.PatorStart();
        }
    }

    public static class XfsPatrolComponentHepler
    {
        public static async void PatorStart(this XfsPatrolComponent self)
        {
            while (true)
            {
                await XfsTimerComponent.Instance.WaitAsync(8000);

                XfsUnit? unit = self.GetParent<XfsUnit>();

                if (unit == null) return;

                Vector3 target = self.GetTarget();

                self.MoveTo(target).Coroutine();
            }
        }

        private static Random ran = new Random();
        private static int nol = 40;
        public static Vector3 GetTarget(this XfsPatrolComponent self)
        {
            Vector3 target = Vector3.zero;

            XfsUnit? unit = self.GetParent<XfsUnit>();

            if (unit == null) return target;

            XfsGrid? targetGrid = new XfsGrid();

            targetGrid.ToObstacle();

            while (targetGrid.Obstacle)
            {
                int ranx = ran.Next(0, nol * 2) - nol;
                int ranz = ran.Next(0, nol * 2) - nol;
                target = new Vector3(unit.StartPosition.x + ranx, 0, unit.StartPosition.z + ranz);
                targetGrid = XfsGridMapComponent.Insatnce?.ToGrid(target);
            }

            return target;
        }

        public static async XfsVoid MoveTo(this XfsPatrolComponent self, Vector3 target)
        {
            
            if ((self.Target - target).magnitude < 0.1f)
            {
                return;
            }            

            self.Target = target;

            XfsUnit unit = self.GetParent<XfsUnit>();
            
            if ((unit.Position - self.Target).magnitude < 0.1f)
            {
                return;
            }
            
            //unit.GetComponent<XfsAstarComponent>().FindPath(self.Target);
            //self.Vector3path = unit.GetComponent<XfsAstarComponent>().Vector3Path;
            //if (self.Vector3path == null || self.Vector3path.Count == 0) return;

            unit.GetComponent<XfsMoveComponent>().CancellationTokenSource?.Cancel();
            unit.GetComponent<XfsMoveComponent>().CancellationTokenSource = new CancellationTokenSource();
                        
            //await self.MoveAsync(self.Vector3path);

            self.BroadcastPathVector(self.Target);
            await unit.GetComponent<XfsMoveComponent>().MoveToAsync(self.Target, unit.GetComponent<XfsMoveComponent>().CancellationTokenSource.Token);

            unit.GetComponent<XfsMoveComponent>().CancellationTokenSource?.Dispose();
            unit.GetComponent<XfsMoveComponent>().CancellationTokenSource = null;
        }

        public static async XfsTask MoveAsync(this XfsPatrolComponent self, List<Vector3> path)
        {
            if (path.Count == 0)
            {
                return;
            }

            //// 第一个点是unit的当前位置，所以不用发送
            for (int i = 1; i < path.Count; ++i)
            {
                //// 每移动3个点发送下3个点给客户端
                if (i % 3 == 1)
                {
                    self.BroadcastPath(path, i, 3);
                }

                Vector3 v3 = path[i];

                XfsUnit? unit = self.GetParent<XfsUnit>();

                if (unit == null) return;

                await unit.GetComponent<XfsMoveComponent>().MoveToAsync(v3, unit.GetComponent<XfsMoveComponent>().CancellationTokenSource.Token);
            }
        }

        public static void BroadcastPathVector(this XfsPatrolComponent self, Vector3 v3)
        {
            XfsUnit? unit = self.GetParent<XfsUnit>();

            if (unit == null) return;

            if (XfsGame.XfsSence.GetComponent<XfsNetOuterComponent>().Sessions.Count > 0)
            {
                C4S_Vector c4S_Vector = new C4S_Vector() { px = v3.x, py = 0, pz = v3.z };

                foreach (var tem in XfsGame.XfsSence.GetComponent<XfsNetOuterComponent>().Sessions.Values)
                {
                    if (tem.IsRunning)
                    {
                        c4S_Vector.ActorId = XfsGame.XfsSence.GetComponent<XfsUnitComponent>().GetInstanceId(tem, unit.Id);
                        tem.Send(c4S_Vector);
                    }
                }
            }

        }

        ////从index找接下来3个点，广播
        public static void BroadcastPath(this XfsPatrolComponent self, List<Vector3> path, int index, int offset)
        {
            //    XfsUnit unit = self.GetParent<XfsUnit>();
            //    Vector3 unitPos = unit.Position;

            //    M2C_PathfindingResult m2CPathfindingResult = new M2C_PathfindingResult();
            //    m2CPathfindingResult.X = unitPos.x;
            //    m2CPathfindingResult.Y = unitPos.y;
            //    m2CPathfindingResult.Z = unitPos.z;
            //    m2CPathfindingResult.Id = unit.Id;

            //    for (int i = 0; i < offset; ++i)
            //    {
            //        if (index + i >= self.ABPath.Result.Count)
            //        {
            //            break;
            //        }
            //        Vector3 v = self.ABPath.Result[index + i];
            //        m2CPathfindingResult.Xs.Add(v.x);
            //        m2CPathfindingResult.Ys.Add(v.y);
            //        m2CPathfindingResult.Zs.Add(v.z);
            //    }
            //    MessageHelper.Broadcast(m2CPathfindingResult);
        }





    }
}
